package frege.control.Category where

infixr 1 `>>>` `<<<`

class Semigroupoid c where
    --- morphism composition
    o :: c j k -> c i j -> c i k

{-- 
A class for categories.
identity and o must form a monoid.
-}
class Category Semigroupoid c => c where
    --- the identity morphism
    identity :: c a a

-- function wrapper
-- TODO replace when function-as-instance feature is available 
data F a b = F { run :: (a -> b) }

instance Semigroupoid F where
     f `o` g = F (F.run f <~ F.run g)

instance Category F where
    identity = F id

--- Right-to-left composition
(<<<) :: Semigroupoid cat => cat b c -> cat a b -> cat a c
(<<<) = o

--- Left-to-right composition
(>>>) :: Semigroupoid cat => cat a b -> cat b c -> cat a c
f >>> g = g `o` f